﻿using System;
using new_problem;

namespace new_problem
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            //CalculateMethods();
            AutomatedWoStabilizing();
            //CalculateFromFile();
        }


        // вычисление обратной задачи гравиметрии для одной поверхности пятью способами
        private static void CalculateMethods()
        {
            Double[] x = DataGen.GetX();
            Double[] y = DataGen.GetY();

            Double[,] surface = DataGen.GetSurfaceGrid(x, y); // строим поверхность
            IOUtils.PrintGridToFile(x, y, surface, "surface");
            //Double[,] smoothedSurface = GaussianBlur.AddGaussBlur5(surface); // adding Gaussian Blur
            //IOUtils.PrintGridToFile(x, y, smoothedSurface, "SmoothedSurface");

            Double[,] field = DataGen.GetFieldGrid(x, y, surface); // прямая задача
            IOUtils.PrintGridToFile(x, y, field, "field");
            
            /*Noise noise = new Noise(); // to add noise
            field = noise.addNoise(field, 0.0001, 0.01, 1); // последний параметр 0 - Gaussian Noise, 1 - White Noise, 2 - Impulse Noise
            IOUtils.PrintGridToFile(x, y, field, "NoiseField");*/

            DataBuffer db = new DataBuffer();
            DateTime dt = new DateTime();
            dt = DateTime.Now;

            IOUtils.PrintGridToFile(x, y, LocalCorrections.CalcLocalCorrections(field, x, y, db), "Local Corrections");
            TimeSpan tlc = DateTime.Now.Subtract(dt); dt = DateTime.Now;
            IOUtils.PrintGridToFile(x, y, MinimalError.CalcMinError(field, x, y, db), "MinError");
            TimeSpan tme = DateTime.Now.Subtract(dt); dt = DateTime.Now;
            IOUtils.PrintGridToFile(x, y, FastestWay.CalcFastestWay(field, x, y, db), "Fastest Way");
            TimeSpan tfw = DateTime.Now.Subtract(dt); dt = DateTime.Now;
            /*IOUtils.PrintGridToFile(x, y, Landweber.CalcLandweber(field, x, y, db), "Landweber");
            TimeSpan tl = DateTime.Now.Subtract(dt); dt = DateTime.Now;*/
            IOUtils.PrintGridToFile(x, y, LevenbergMarquardt.calcLevenbergMarquardt(field, x, y, db), "L_marquardt");
            TimeSpan tlm = DateTime.Now.Subtract(dt); 
            IOUtils.PrintDataToFile(
                "Local Corrections: " + tlc.TotalSeconds + " sec, " + db.Lc + " iterations " + db.LcErr +
                " absolute error\r\n" +
                "Minimal Error: " + tme.TotalSeconds + " sec, " + db.Me + " iterations " + db.MeErr +
                " absolute error\r\n" + "Fastest Way: " + tfw.TotalSeconds + " sec, " + db.Fw + " iterations " + db.FwErr +
                " absolute error\r\n" +
                /*"Landweber: " + tl.TotalSeconds + " sec, " + db.L + " iterations " + db.LErr +
                " absolute error\r\n" + */
                "LevenbergMarquardt: " + tlm.TotalSeconds + " sec, " + db.LM + " iterations " + db.LMErr +
                " absolute error\r\n", "executionInfo");
        }

        //решение обратной задачи (для всех 7 поверхностей) градиентными методамиы
        public static void AutomatedWoStabilizing()
        {
            Double[] x = DataGen.GetX();
            Double[] y = DataGen.GetY();

            for (int i = 0; i < 7; i++)
            {
                Double[,] surface = SurfaceSet.GetSurfaceGrid(x, y, i);

                IOUtils.PrintGridToFile(x, y, surface, i + "_surface");

                //Double[,] smoothedSurface = GaussianBlur.AddGaussBlur5(surface); // to add Gaussian Blur
                //IOUtils.PrintGridToFile(x, y, smoothedSurface, "SmoothedSurface_" + i);

                Double[,] field = DataGen.GetFieldGrid(x, y, surface);
                IOUtils.PrintGridToFile(x, y, field, i + "_field");

                // to add noise
                Noise noise = new Noise(); 
                        // 0 - Gaussian Noise, 1 - White Noise, 2 - Impulse Noise
                field = noise.addNoise(field, 0.00007, 0.10, 1);
                IOUtils.PrintGridToFile(x, y, field, i + "_NoiseField");

                DataBuffer db = new DataBuffer();
                DateTime dt = new DateTime();
                dt = DateTime.Now;
                IOUtils.PrintGridToFile(x, y, MinimalError.CalcMinError(field, x, y, db), i + "_MinError");
                TimeSpan tme = DateTime.Now.Subtract(dt);
                dt = DateTime.Now;
                IOUtils.PrintGridToFile(x, y, FastestWay.CalcFastestWay(field, x, y, db), i + "_Fastest Way");
                TimeSpan tfw = DateTime.Now.Subtract(dt);
                dt = DateTime.Now;
                IOUtils.PrintGridToFile(x, y, LocalCorrections.CalcLocalCorrections(field, x, y, db), i + "_Local Corrections");
                TimeSpan tlc = DateTime.Now.Subtract(dt);
                dt = DateTime.Now;
                IOUtils.PrintGridToFile(x, y, LevenbergMarquardt.calcLevenbergMarquardt(field, x, y, db), i + "_Levenberg_marquardt");
                TimeSpan tlm = DateTime.Now.Subtract(dt);
                IOUtils.PrintDataToFile(
                     "Minimal Error: " + tme.TotalSeconds + " sec, " + db.Me + " iterations " + db.MeErr +
                     " absolute error\r\nFastest Way: " + tfw.TotalSeconds + " sec, " + db.Fw + " iterations " + db.FwErr +
                     " absolute error\r\n" + "Local Corections: " + tlc.TotalSeconds + " sec, " + db.Lc + " iterations " + db.LcErr +
                     " absolute error\r\nLevengerg-Marquardt: " + tlm.TotalSeconds + " sec, " + db.LM + " iterations " + db.LMErr +
                     " absolute error\r\n", i + "_executionInfo");
            }

        }

        // решение в случае входного файла с полем
        public static void CalculateFromFile()
        {
            Double[] x = DataGen.GetX();
            Double[] y = DataGen.GetY();

            double[,] field = new double[DataGen.N + 1, DataGen.N + 1];
            IOUtils.readDataFromFile("out.dat", x, y, field);

            /*Noise noise = new Noise(); // to add noise
            field = noise.addNoise(field, 0.0001, 0.01, 1); // последний параметр 0 - Gaussian Noise, 1 - White Noise, 2 - Impulse Noise
            IOUtils.PrintGridToFile(x, y, field, "NoiseField");*/

            DataBuffer db = new DataBuffer();
            DateTime dt = new DateTime();
            dt = DateTime.Now;

            IOUtils.PrintGridToFile(x, y, LocalCorrections.CalcLocalCorrections(field, x, y, db), "Local Corrections_out");
            TimeSpan tlc = DateTime.Now.Subtract(dt); dt = DateTime.Now;
            IOUtils.PrintGridToFile(x, y, MinimalError.CalcMinError(field, x, y, db), "MinError_out");
            TimeSpan tme = DateTime.Now.Subtract(dt); dt = DateTime.Now;
            IOUtils.PrintGridToFile(x, y, FastestWay.CalcFastestWay(field, x, y, db), "Fastest Way_out");
            TimeSpan tfw = DateTime.Now.Subtract(dt); dt = DateTime.Now;
            IOUtils.PrintGridToFile(x, y, LevenbergMarquardt.calcLevenbergMarquardt(field, x, y, db), "L_marquardt_out");
            TimeSpan tlm = DateTime.Now.Subtract(dt); 
            IOUtils.PrintDataToFile(
                "Local Corrections: " + tlc.TotalSeconds + " sec, " + db.Lc + " iterations " + db.LcErr +
                " absolute error\r\n" +
                "Minimal Error: " + tme.TotalSeconds + " sec, " + db.Me + " iterations " + db.MeErr +
                " absolute error\r\n" + "Fastest Way: " + tfw.TotalSeconds + " sec, " + db.Fw + " iterations " + db.FwErr +
                " absolute error\r\n" +
               "LevenbergMarquardt: " + tlm.TotalSeconds + " sec, " + db.LM + " iterations " + db.LMErr +
                " absolute error\r\n", "executionInfo_out");

        }
    }
}